package com.zhuozhou.jdyc.api;


import com.zhuozhou.jdyc.BuildConfig;
import com.zhuozhou.jdyc.base.BaseConverterFactory;
import com.zhuozhou.jdyc.util.apiUtil.DateUtil;
import com.zhuozhou.jdyc.util.jiami.MD5Util;
import com.zhuozhou.jdyc.util.jiami.RSAUtils;
import com.zhuozhou.jdyc.util.log.LogUtil;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

/**
 * Created by 方舟 on 2019/8/1.
 * describe：Retrofit初始化
 */

public class ApiRetrofit {

    public final static String BASE_URL = "https://yuncang.dzsmxx.com/api/";
    public final static String BASE_DEBUG_URL = "https://yuncang.dzsmxx.com/api/";
    private String key = "ca6dbbe3333a079b";
    private String siteid = "0";
    private static ApiRetrofit apiRetrofit;
    private Retrofit retrofit;
    private OkHttpClient client;
    private ApiServiceHelper apiServiceHelper;

    /**
     * 动态修改url
     */
    private Interceptor urlInterceptor = chain -> {
        // 获取request
        Request request = chain.request();
        // 从request中获取原有的HttpUrl实例oldHttpUrl
        HttpUrl oldHttpUrl = request.url();
        // 获取request的创建者builder
        Request.Builder builder = request.newBuilder();
        // 从request中获取headers，通过给定的键url_name
        List<String> headerValues = request.headers("x-url");
        if (headerValues.size() > 0) {
            // 如果有这个header，先将配置的header删除，因此header仅用作app和okhttp之间使用
            builder.removeHeader("x-url");
            // 匹配获得新的BaseUrl
            String headerValue = headerValues.get(0);
            HttpUrl newBaseUrl = null;
            if ("sub".equals(headerValue)) {
                newBaseUrl = HttpUrl.parse(UserAccountHelper.getBaseUrl());
            } else if ("admin".equals(headerValue)) {
                newBaseUrl = HttpUrl.parse(BuildConfig.DEBUG ? BASE_DEBUG_URL : BASE_URL);
            } else {
                newBaseUrl = oldHttpUrl;
            }
            // 重建新的HttpUrl，修改需要修改的url部分
            HttpUrl newFullUrl = oldHttpUrl
                    .newBuilder()
                    // 更换网络协议
                    .scheme(newBaseUrl.scheme())
                    // 更换主机名
                    .host(newBaseUrl.host())
                    // 更换端口
                    .port(newBaseUrl.port())
                    .build();
            // 重建这个request，通过builder.url(newFullUrl).build()；
            // 然后返回一个response至此结束修改
            return chain.proceed(builder.url(newFullUrl).build());
        }
        return chain.proceed(request);
    };

    /**
     * 请求访问quest
     * response拦截器
     * 日志拦截器
     */
    private Interceptor logInterceptor = chain -> {
        String timeStamp = DateUtil.getTimestamp();
        LogUtil.show(UserAccountHelper.getToken() == null ? "" : UserAccountHelper.getToken());
        Request request = chain.request().newBuilder()
                .addHeader("Token", "2e5e8898-9986-4ee1-aafc-f35aa7dc154c")
                //.addHeader("Token", UserAccountHelper.getToken() == null ? "" : UserAccountHelper.getToken())
//                .addHeader("x-timestamp", timeStamp)
//                .addHeader("x-refreshtoken", UserAccountHelper.getRefreshToken() == null ? "" : UserAccountHelper.getRefreshToken())
//                .addHeader("x-uuid", UUID.randomUUID().toString())
//                .addHeader("x-appid", ApiAccountHelper.APPID)
//                .addHeader("x-phoneidentity", ApiAccountHelper.getDeviceId())
//                .addHeader("x-protocolversion", ApiAccountHelper.PROTOCOL_VERSION)
//                .addHeader("x-phoneinfo", ApiAccountHelper.getPhoneInfo())
//                .addHeader("x-sign", encodeSign(bodyToString(chain.request().body()), timeStamp))
                .addHeader("zhuozhoutoken", encodeToken(key, timeStamp))
                .addHeader("siteid", siteid)
                .build();
        Response response = chain.proceed(request);
        if (BuildConfig.DEBUG) {
            printLog(request, response);
        }
        return response;
    };

    private void printLog(final Request request, final Response response) {
        LogUtil.show("--------------------Request Start--------------------");

        LogUtil.show("Method：" + request.method());
        LogUtil.show("Url：" + request.url());
        LogUtil.show("HttpHeader：" + request.headers().toString());

        try {
            LogUtil.show("请求参数：" + bodyToString(request.body()));
        } catch (IOException e) {
            LogUtil.show("请求参数解析失败");
        }
        try {
            ResponseBody responseBody = response.peekBody(1024 * 2048);
            LogUtil.show("返回结果：" + responseBody.string());
        } catch (Exception e) {
            LogUtil.show("返回结果解析失败");
        }
        LogUtil.show("--------------------Request End--------------------");
    }

    private String bodyToString(final RequestBody request) throws IOException {
        final Buffer buffer = new Buffer();
        if (request != null) {
            request.writeTo(buffer);
        } else {
            return "";
        }
        return buffer.readUtf8();
    }

    private ApiRetrofit() {
        client = new OkHttpClient.Builder()
                //添加log拦截器
//                .addInterceptor(urlInterceptor)
                .addInterceptor(logInterceptor)
                .connectTimeout(15, TimeUnit.SECONDS)
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(BuildConfig.DEBUG ? BASE_DEBUG_URL : BASE_URL)
                .addConverterFactory(BaseConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())//支持RxJava2
                .client(client)
                .build();

        apiServiceHelper = retrofit.create(ApiServiceHelper.class);
    }

    public static ApiRetrofit getInstance() {
        if (apiRetrofit == null) {
            synchronized (Object.class) {
                if (apiRetrofit == null) {
                    apiRetrofit = new ApiRetrofit();
                }
            }
        }
        return apiRetrofit;
    }

    public ApiServiceHelper getApiService() {
        return apiServiceHelper;
    }

    private String encodeSign(String postJson, String timeStamp) {
        try {
            return MD5Util.md5Encode(("x-appsecret" + ApiAccountHelper.APPSECRET + postJson + "x-timestamp" + timeStamp).toUpperCase()).toUpperCase();
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.show("签名计算异常：" + e);
        }
        return "";
    }

    private String encodeToken(String key, String timeStamp) {
        try {
            String code = timeStamp + " " + siteid;
            return RSAUtils.aesEncrypt(key, code);
        } catch (Exception e) {
            e.printStackTrace();
            LogUtil.show("签名计算异常：" + e);
        }
        return "";
    }

}
